package anno.ioc;


import anno.Autowired;

import javax.servlet.*;
import javax.servlet.annotation.HandlesTypes;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServlet;
import java.lang.reflect.Field;
import java.util.Set;

@HandlesTypes(HttpServlet.class)
@WebListener
public class ServletInjector implements ServletContainerInitializer, ServletContextListener {

    @Override
    public void onStartup(Set<Class<?>> servletClasses, ServletContext ctx) throws ServletException {
        if (servletClasses == null || servletClasses.isEmpty()) {
            return;
        }
        // ServletInjector已经实现了ServletContextListener，直接注册自己
        ctx.addListener(this);
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("Web应用程序启动，初始化BeanFactory...");
        // BeanFactory初始化
        String basePackage = sce.getServletContext().getInitParameter("basePackage");
        if (basePackage == null || basePackage.trim().isEmpty()) {
            basePackage = "";
        }
        BeanFactory.initBeans(basePackage);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("Web应用程序关闭，清理BeanFactory...");
        BeanFactory.clearBeans();
    }

    /**
     * 为Servlet注入依赖的具体实现
     */
    public static void inject(HttpServlet servlet) {
        if (servlet == null) return;

        Class<?> servletClass = servlet.getClass();
        System.out.println("正在检查Servlet是否需要依赖注入: " + servletClass.getName());

        // 获取所有字段（包括私有字段）
        for (Field field : servletClass.getDeclaredFields()) {
            if (field.isAnnotationPresent(Autowired.class)) {
                try {
                    field.setAccessible(true);
                    // 从BeanFactory获取依赖实例
                    Object dependency = BeanFactory.getBean(field.getType());
                    if (dependency != null) {
                        field.set(servlet, dependency);
                        System.out.println("成功注入依赖: " + servletClass.getName() + 
                            " => " + field.getType().getName());
                    } else {
                        System.err.println("警告: 找不到类型为 " + field.getType().getName() + 
                            " 的Bean，该类型被 " + servletClass.getName() + " 所依赖");
                    }
                } catch (Exception e) {
                    System.err.println("注入依赖失败: " + servletClass.getName() + 
                        " => " + field.getName());
                    e.printStackTrace();
                }
            }
        }
    }
}